home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-06-06 | 9.5 KB | 341 lines |
- import java.applet.Applet;
- import java.applet.AudioClip;
- import java.lang.Math;
- import java.util.Random;
- import java.util.Date;
- import java.awt.*;
-
- public class ShootSaucer extends Applet implements Runnable {
- static final int ENEMY = 6; // 敵は最大6機
- static final int WIDTH = 320, HEIGHT = 240; // 背景サイズ
- SpriteCanvas sc; // スプライトキャンバス
- int mx, my, mbx, mby; // 自分の座標とミサイルの座標
- int ex[] = new int[ENEMY], ey[] = new int[ENEMY]; // 敵の座標
- int ebx[] = new int[ENEMY], eby[] = new int[ENEMY]; // 敵の弾の座標
- int count[] = new int[ENEMY], direct[] = new int[ENEMY]; // 敵の回転
- int edx[] = new int[ENEMY], edy[] = new int[ENEMY]; // 敵の弾の速度
- int score; // スコア
- boolean mbf, ef[] = new boolean[ENEMY], ebf[] = new boolean[ENEMY];
- // 自分のミサイル、敵、敵の弾の表示フラグ
- boolean up, down, left, right, space; // キー入力フラグ
- Thread thread=null;
- MediaTracker mt;
- Random aRandom = new Random();
- Math aMath;
- Label Score;
- boolean play = false; // ゲーム中フラグ
- AudioClip gun, bomb, wow, hit[] = new AudioClip[4];
- public void init(){
- Image image;
- int i;
- // 効果音読み込み
- gun = getAudioClip( getDocumentBase(), "audio/gun.au" );
- bomb = getAudioClip( getDocumentBase(), "audio/bomb.au" );
- wow = getAudioClip( getDocumentBase(), "audio/wow.au" );
- hit[0] = getAudioClip( getDocumentBase(), "audio/comeon.au" );
- hit[1] = getAudioClip( getDocumentBase(), "audio/get.au" );
- hit[2] = getAudioClip( getDocumentBase(), "audio/iyao.au" );
- hit[3] = getAudioClip( getDocumentBase(), "audio/wao.au" );
- // スプライトキャンバス作成
- // パターンは、自機、ミサイル、敵6パターン、敵の弾、爆発
- // プレーンは、自機、ミサイル、敵6機、敵の弾6発
- sc = new SpriteCanvas( 1+1+6+1+1, 1+1+ENEMY+ENEMY, WIDTH, HEIGHT, this );
- setLayout( new BorderLayout() );
- score = 0;
- Score = new Label( "SCORE "+score, Label.CENTER );
- add( "Center", sc );
- add( "North", Score );
- add( "South", new Button( "Start" ) );
- mt = new MediaTracker( this );
- image = getImage( getDocumentBase(), "image/earth.gif" ); // 背景
- mt.addImage( image, 0 );
- sc.WaitLoadImage( mt, 0 ); // 読み込むまでスプライトを表示しない
- sc.SetBGImage( image ); // 背景に設定
- image = getImage( getDocumentBase(), "image/Fighter.gif" ); // 自機
- mt.addImage( image, 0 );
- sc.Define( 0, image ); // パターン0に設定
- image = getImage( getDocumentBase(), "image/Missile.gif" ); // ミサイル
- mt.addImage( image, 0 );
- sc.Define( 1, image ); // パターン1に設定
- for( i=1; i<=6; i++ ){
- // 敵の回転6パターン
- image = getImage( getDocumentBase(), "image/Enemy"+i+".gif" );
- mt.addImage( image, 0 );
- sc.Define( i+1, image ); // パターン2~7に設定
- }
- image = getImage( getDocumentBase(), "image/Bomb.gif" ); // 敵の弾
- mt.addImage( image, 0 );
- sc.Define( 8, image ); // パターン8に設定
- image = getImage( getDocumentBase(), "image/Crush.gif" ); // 爆発
- mt.addImage( image, 0 );
- sc.Define( 9, image ); // パターン9に設定
- for( i=0; i<ENEMY; i++ ) ef[i] = ebf[i] = false;
- // 速いインタプリタなら、下のコメントを取った方がいいかも
- // sc.SetClipMode( true );
- }
- public void start(){
- if( thread==null ){
- thread = new Thread( this );
- thread.start();
- }
- }
- public void stop(){
- if( thread!=null ){
- thread.stop();
- thread = null;
- }
- }
- public void run(){
- try {
- mt.waitForID( 0 );
- } catch( InterruptedException e ){
- return;
- }
- while( true ){
- try {
- Thread.sleep( 50 );
- } catch( InterruptedException e ){
- break;
- }
- for( int i=0; i<ENEMY; i++ ){ // 敵の動き
- int r = aMath.abs(aRandom.nextInt());
- if( ef[i]==false ){ // 敵は出ていない
- sc.Hide( i+ENEMY+2, i+ENEMY+2 );
- if( (r&0x7f)<=score>>3 ) InitEnemy( i ); // 出現
- } else {
- switch( direct[i] ){ // 回転の向き
- case 1:// 左向き
- count[i]++;
- if( count[i]>=6 ) count[i] = 0;
- sc.Set( i+ENEMY+2, count[i]+2 ); // 回転
- ex[i] -= 2;
- break;
- case 2:// 右向き
- count[i]--;
- if( count[i]<0 )count[i] = 5;
- sc.Set( i+ENEMY+2, count[i]+2 ); // 回転
- ex[i] += 2;
- break;
- default:// 回転してない
- switch( r&0x3f ){
- case 1: // 左向き回転させる
- direct[i] = 1;
- count[i] = 1;
- // 弾発射
- if( ((r>>8)&0xff)<score ) Bomb( i );
- break;
- case 2: // 右向き回転させる
- direct[i] = 2;
- count[i] = 5;
- // 弾発射
- if( ((r>>8)&0xff)<score ) Bomb( i );
- break;
- }
- }
- }
- if( ef[i] ){
- ey[i] += 4;
- if( ey[i]>240 ){ // 画面から出ていった
- ef[i] = false;
- sc.Hide( i+ENEMY+2, i+ENEMY+2 ); // スプライト非表示
- } else sc.Move( i+ENEMY+2, ex[i], ey[i] ); // 移動
- }
- if( ebf[i] ){
- ebx[i] += edx[i];
- eby[i] += edy[i];
- if( ebx[i]<-32 || ebx[i]>WIDTH ||
- eby[i]<-32 || eby[i]>HEIGHT ){ // 弾が出ていった
- sc.Hide( i+2, i+2 ); // スプライト非表示
- ebf[i] = false;
- } else {
- sc.Move( i+2, ebx[i], eby[i] ); // 移動
- }
- }
- }
- if( play ){ // ゲーム中
- // キー判定
- if( up && !down ) if( my>4 ) my -= 4;
- if( down && !up ) if( my<HEIGHT-32-4 ) my += 4;
- if( left && !right ) if( mx>4 ) mx -= 4;
- if( right && !left ) if( mx<WIDTH-32-4 ) mx += 4;
- sc.Move( 0, mx, my ); // 移動
- // ミサイルが出ていないときにスペースキーを押した
- if( space && !mbf ){
- mbx = mx;
- mby = my;
- mbf = true;
- sc.Set( 1, 1 ); // ミサイルプレーンをセット
- sc.Show( 1, 1 ); // ミサイルプレーンを表示
- gun.play(); // SE
- }
- if( mbf ){ // ミサイルが出ている
- mby -= 16;
- if( mby<-32 ){
- sc.Hide( 1, 1 ); // 画面から出ていった
- mbf = false;
- } else {
- if( HitCheck() ){ // 敵との当たり判定
- mbf = false;
- sc.Hide( 1, 1 ); // ヒットしたらミサイルも消す
- } else sc.Move( 1, mbx, mby ); // 移動
- }
- }
- if( CrushCheck() ){ // 自機の敵および敵の弾との当たり判定
- sc.Set( 0, 9 ); // 死んじゃった
- sc.Hide( 1, 1 );
- play = false;
- }
- }
- sc.Draw(); // スプライト描画
- }
- }
- void InitEnemy( int n ){ // 敵の初期化
- ex[n] = aMath.abs(aRandom.nextInt())%(WIDTH-32);
- ey[n] = -32;
- ef[n] = true;
- direct[n] = 0;
- sc.Set( n+ENEMY+2, 2 ); // プレーンセット
- sc.Show( n+ENEMY+2, n+ENEMY+2 ); // 表示
- }
- boolean HitCheck() // ミサイルと敵の当たり判定
- {
- boolean result = false;
- for( int i=0; i<ENEMY; i++ ){
- if( ef[i] ){ // 敵は出ている?
- if( ex[i]>mbx-16 && ex[i]<mbx+16 &&
- ey[i]>mby-20 && ey[i]<mby+20 ){ // 当たり
- ef[i] = false;
- sc.Set( i+ENEMY+2, 9 ); // 敵プレーンに爆発パターンをセット
- score += 1;
- Score.setText( "SCORE "+score );
- result = true;
- int r = aMath.abs(aRandom.nextInt());
- hit[r%4].play(); // SE
- if( (r&0xf)<score>>3 ) Bomb( i ); // 打ち返してきた
- break;
- }
- }
- }
- return result;
- }
- boolean CrushCheck() // 自機の当たり判定
- {
- boolean result = false;
- for( int i=0; i<ENEMY; i++ ){ // 敵との判定
- if( ef[i] ){ // 敵は出ている?
- if( ex[i]>mx-20 && ex[i]<mx+20 &&
- ey[i]>my-20 && ey[i]<my+20 ){ // 当たり
- ef[i] = false;
- sc.Set( i+ENEMY+2, 9 ); // 敵プレーンに爆発パターンをセット
- score += 1;
- Score.setText( "SCORE "+score );
- result = true;
- bomb.play(); // ドカーン
- break;
- }
- }
- if( ebf[i] ){ // 敵の弾は出ている?
- if( ebx[i]>mx-16 && ebx[i]<mx+16 &&
- eby[i]>my-16 && eby[i]<my+16 ){ // 当たり
- ebf[i] = false;
- sc.Hide( i+2, i+2 ); // 弾を消す
- result = true;
- bomb.play(); // ドカーン
- break;
- }
- }
- }
- return result;
- }
- void Bomb( int i ) // 敵の弾発射
- {
- // 敵の弾が発射済みかゲーム中でなければ発射しない
- if( ebf[i] || !play ) return;
- ebx[i] = ex[i];
- eby[i] = ey[i];
- int dx, dy, ux, uy;
- // 適当に弾の向き設定
- dx = mx-ebx[i];
- dy = my-eby[i];
- ux = dx>=0?dx:-dx;
- uy = dy>=0?dy:-dy;
- if( ux>uy ){
- edx[i] = 5;
- edy[i] = 3;
- } else {
- edx[i] = 3;
- edy[i] = 5;
- }
- if( dx<0 ) edx[i] = -edx[i];
- if( dy<0 ) edy[i] = -edy[i];
- ebf[i] = true;
- sc.Set( i+2, 8 ); // 弾プレーンセット
- sc.Show( i+2, i+2 ); // 表示
- wow.play(); // SE
- }
- public boolean keyDown( Event e, int key ){
- switch( key ){
- case 1004://↑
- up = true;
- break;
- case 1005://↓
- down = true;
- break;
- case 1006:// ←
- left = true;
- break;
- case 1007:// →
- right = true;
- break;
- case ' ':
- space = true;
- break;
- }
- return true;
- }
- public boolean keyUp( Event e, int key ){
- switch( key ){
- case 1004://↑
- up = false;
- break;
- case 1005://↓
- down = false;
- break;
- case 1006:// ←
- left = false;
- break;
- case 1007:// →
- right = false;
- break;
- case ' ':
- space = false;
- break;
- }
- return true;
- }
- public boolean action( Event e, Object o ){
- if( e.target instanceof Button ){
- if( play==false ){ // ゲームスタート
- play = true;
- score = 0;
- Score.setText( "SCORE "+score );
- for( int i=0; i<ENEMY; i++ ){ // 敵の初期化
- ef[i] = false;
- ebf[i] = false;
- }
- sc.Hide(); // 取りあえず全部隠しといて
- mx = (WIDTH-32)/2;
- my = HEIGHT-32-32;
- sc.Set( 0, 0 ); // 自機プレーンセット
- sc.Set( 1, 1 ); // ミサイルプレーンセット
- sc.Move( 0, mx, my ); // 自機の座標設定
- sc.Show( 0, 0 ); // 自機表示
- up = down = left = right = space = false;
- mbf = false;
- }
- return true;
- }
- return false;
- }
- }
-